package com.cskt.filter;

import com.cskt.controller.ValidateCodeController;
import com.cskt.exception.ValidateCodeException;
import com.cskt.handler.CustomHandler;
import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

/**
 * 验证码校验过滤器
 *
 * @author admin
 * @date 2023/05/11 15:17
 **/
@Component
public class ValidateCodeFilter extends OncePerRequestFilter {
    private static final Logger log = LoggerFactory.getLogger(ValidateCodeFilter.class);

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private CustomHandler customHandler;


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //判断当前请求路径是否为login
        try {
            validate(request);
        } catch (ValidateCodeException e) {
//            直接重定向
            response.sendRedirect("/toLoginPage");
//            当前return只为了结束流程，而不需要返回任何值 
            return;
        }
//      后续的过滤器链
        filterChain.doFilter(request, response);

    }

    private void validate(HttpServletRequest request) throws ValidateCodeException {
        if (request.getRequestURI().equals("/login")
                && request.getMethod().equalsIgnoreCase("post")) {
//       1、先获取请求ip地址
            String remoteAddr = request.getRemoteAddr();
//            2、从redis中取出code
            String key = ValidateCodeController.REDIS_KEY_IMAGE_CODE + "-" + remoteAddr;
            String code = stringRedisTemplate.boundValueOps(key).get();
//            从请求体中取出图片验证码
            String imageCode = request.getParameter("imageCode");
//            判断从前端 传递过来的验证码是否为空
            if (!StringUtils.hasText(imageCode)) {
                log.warn("请求传递的验证码为空");
                throw new ValidateCodeException("验证码不能为空");
            }
//            如果从redis中取出的验证码为空，则表示验证码已失效
            if (!StringUtils.hasText(code)) {
                log.warn("验证码已失效");
//                抛出自定义异常
                throw new ValidateCodeException("验证码已失效");
            }
            if (!imageCode.equals(code)) {
                log.warn("验证码错误");
                throw new ValidateCodeException("验证码错误");
            }
//            验证成功后，删除redis中的验证码
            stringRedisTemplate.delete(key);
        }
    }
}
